using System;
using System.Diagnostics;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Data;

namespace ButtonHitter {
	public class Form1 : System.Windows.Forms.Form {
		private System.Windows.Forms.Timer tmrHit;
		private System.Windows.Forms.StatusBar stBar;
		private System.Windows.Forms.TextBox txtWindows;
		private TextBox txtStrokes;
		private System.ComponentModel.IContainer components;

		public Form1() {
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
			Form1.CheckForIllegalCrossThreadCalls = false;

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing ) {
			if( disposing ) {
				if (components != null) {
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent() {
			this.components = new System.ComponentModel.Container();
			this.tmrHit = new System.Windows.Forms.Timer(this.components);
			this.stBar = new System.Windows.Forms.StatusBar();
			this.txtWindows = new System.Windows.Forms.TextBox();
			this.txtStrokes = new System.Windows.Forms.TextBox();
			this.SuspendLayout();
			// 
			// tmrHit
			// 
			this.tmrHit.Enabled = true;
			this.tmrHit.Interval = 1000;
			this.tmrHit.Tick += new System.EventHandler(this.tmrHit_Tick);
			// 
			// stBar
			// 
			this.stBar.Location = new System.Drawing.Point(0, 219);
			this.stBar.Name = "stBar";
			this.stBar.Size = new System.Drawing.Size(457, 22);
			this.stBar.TabIndex = 1;
			// 
			// txtWindows
			// 
			this.txtWindows.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
									| System.Windows.Forms.AnchorStyles.Left)
									| System.Windows.Forms.AnchorStyles.Right)));
			this.txtWindows.Location = new System.Drawing.Point(0, 0);
			this.txtWindows.Multiline = true;
			this.txtWindows.Name = "txtWindows";
			this.txtWindows.Size = new System.Drawing.Size(457, 107);
			this.txtWindows.TabIndex = 2;
			// 
			// txtStrokes
			// 
			this.txtStrokes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
									| System.Windows.Forms.AnchorStyles.Right)));
			this.txtStrokes.Location = new System.Drawing.Point(0, 113);
			this.txtStrokes.Multiline = true;
			this.txtStrokes.Name = "txtStrokes";
			this.txtStrokes.Size = new System.Drawing.Size(457, 116);
			this.txtStrokes.TabIndex = 2;
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(457, 241);
			this.Controls.Add(this.txtStrokes);
			this.Controls.Add(this.txtWindows);
			this.Controls.Add(this.stBar);
			this.MaximizeBox = false;
			this.Name = "Form1";
			this.Text = "Button Hitter";
			this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
			this.Load += new System.EventHandler(this.Form1_Load);
			this.ResumeLayout(false);
			this.PerformLayout();

		}
		#endregion

		#region DiiImport
		private const int GWL_EXSTYLE = (-20);
		private const int WS_EX_TOOLWINDOW = 0x80;
		private const int WS_EX_APPWINDOW = 0x40000;

		public const int GW_HWNDFIRST = 0;
		public const int GW_HWNDLAST = 1;
		public const int GW_HWNDNEXT = 2;
		public const int GW_HWNDPREV = 3;
		public const int GW_OWNER = 4;
		public const int GW_CHILD = 5;

		[DllImport("User32.dll")]
		public static extern Int32 FindWindow(string lpClassName,string lpWindowName);
		
		[DllImport("User32.dll")]
		public static extern Int32 SetForegroundWindow(int hWnd);
		
		[DllImport("User32.dll")]
		public static extern Boolean EnumChildWindows(int hWndParent,Delegate lpEnumFunc,int lParam);
		
		[DllImport("User32.dll")]
		public static extern Int32 GetWindowText(int hWnd,StringBuilder s,int nMaxCount);
		
		[DllImport("User32.dll")]
		public static extern Int32 GetWindowTextLength(int hwnd);

		[DllImport("user32.dll", EntryPoint="GetDesktopWindow")]
		public static extern int GetDesktopWindow();

		[DllImport("user32")]
		public static extern int GetWindow(int hwnd, int wCmd);

		[DllImport("user32")]
		public static extern int IsWindowVisible(int hwnd);
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
		bool busy = false;
		private void tmrHit_Tick(object sender, System.EventArgs e) {
			if( WindowState != FormWindowState.Minimized || busy )return;
			PushButtons();
			//if( !CheckOutlook() )this.Close();
			//Thread t = new Thread(new ThreadStart(PushButtons));
			//t.Start();
			//t.Join(2 * 1000);
			//if (t.IsAlive) t.Abort();
		}
		string delim = ConfigurationSettings.AppSettings["delim"];
		char keydelim = ConfigurationSettings.AppSettings["keydelim"][0];
		private void PushButtons(){
			busy = true;
			try{
				foreach( string windowName in  Regex.Split(txtStrokes.Text,Environment.NewLine) )
					try{
						PushButton(windowName);
					} catch (ThreadAbortException) {
						return;
					} catch (Exception exc) {
						txtWindows.Text = exc.Message;
						Application.DoEvents();
					}
			}finally{
				busy = false;
			}
		}
		private bool PushButton(string windowName){
			string keys = "{ESC}";
			bool ret = true;
			if( windowName.Split('|').Length > 1 ){
				keys = windowName.Split('|')[1];
				windowName = windowName.Split('|')[0];
			}
			int  wHnd = FindWindow(null,windowName);
			string status = "Idle";
			if( wHnd > 0 ){
				if( SetForegroundWindow(wHnd) > 0 ){
					Thread.Sleep(0);
					SendKeys.SendWait(keys);
					status = "Hit";
				}else
					status = "Miss";
			}
			stBar.Text = status + " @ " + DateTime.Now;
			return ret;
			//this.TopLevel = false;	
		}
		private bool CheckOutlook(){
			foreach( Process proc in Process.GetProcesses() )
				if( proc.ProcessName.ToLower().StartsWith("outlook") )return true;
			return false;
		}

		private void Form1_Load(object sender, System.EventArgs e) {
			tmrHit.Interval = int.Parse(ConfigurationSettings.AppSettings["delay"]);
			txtStrokes.Text = ConfigurationSettings.AppSettings["names"].Replace(delim, Environment.NewLine);
			GetTaskWindows();
		}
		private void GetTaskWindows() {
			txtWindows.Text = "";
			// Get the desktopwindow handle
			int nDeshWndHandle = GetDesktopWindow();
			// Get the first child window
			int nChildHandle = GetWindow(nDeshWndHandle, GW_CHILD);

			while (nChildHandle != 0) {
				//If the child window is this (SendKeys) application then ignore it.
				if (nChildHandle == this.Handle.ToInt32()) {
					nChildHandle = GetWindow(nChildHandle, GW_HWNDNEXT);
				}

				// Get only visible windows
				if (IsWindowVisible(nChildHandle) != 0) {
					StringBuilder sbTitle = new StringBuilder(1024);
					// Read the Title bar text on the windows to put in combobox
					GetWindowText(nChildHandle, sbTitle, sbTitle.Capacity);
					String sWinTitle = sbTitle.ToString();
					{
						if (sWinTitle.Length > 0) {
							txtWindows.Text+= sWinTitle+Environment.NewLine;
						}
					}
				}
				// Look for the next child.
				nChildHandle = GetWindow(nChildHandle, GW_HWNDNEXT);
			}
		}
	}
}
